package com.drools.project.config;

import jakarta.annotation.Resource;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieModule;
import org.kie.api.runtime.KieContainer;
import org.kie.internal.io.ResourceFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;

/**
 * @author hulei
 * 规则文件的配置类
 */
@Configuration
public class DroolsConfig {

    /**
     * 外部规则文件路径配置类
     */
    @Resource
    private DroolsFilePathConfig droolsFilePathConfig;

    /**
     * classpath路径下的规则文件根路径
     */
    private static final String CLASSPATH_RULES_PATH = "src/main/resources/";

    /**
     * 创建KieServices对象
     */
    private static final KieServices kieServices = KieServices.Factory.get();

//===========================================内部classPath下drools文件加载方式,不推荐此种方式==================================

    /**
     * 本方法规则为写死的，实际开发中不灵活，当规则文件需要动态变换时，则不适用
     */
    @Bean
    public KieContainer kieContainer() throws IOException {
        KieFileSystem kfs = kieServices.newKieFileSystem();
        Files.walkFileTree(Paths.get(CLASSPATH_RULES_PATH), new SimpleFileVisitor<>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
                if (file.toString().endsWith(".drl")) {
                    kfs.write(ResourceFactory.newFileResource(file.toFile()));
                }
                return FileVisitResult.CONTINUE;
            }
        });

        KieBuilder kb = kieServices.newKieBuilder(kfs);
        kb.buildAll();
        KieModule kieModule = kb.getKieModule();
        return kieServices.newKieContainer(kieModule.getReleaseId());
    }


//===========================================外部drools文件加载方式,推荐此种方式==============================================
//
//    /**
//     * 动态获取外部规则文件,可以获取多个规则文件,解析加载
//     * kfs.write("src/main/resources/rules/" + ruleFile.getName(),
//     * kieServices.getResources().newFileSystemResource(ruleFile));
//     * 这里的规则文件从ruleFile读取后写入到classpath路径下src/main/resources/rules/
//     * 是虚拟的,实际并不生成文件,需要注意的是虚拟路径的前缀必须是src/main/resources,否则报错
//     * 至于resources后面的路径可以随意写,也可以不写
//     */
//    @Bean
//    public KieContainer kieContainer() throws IOException {
//        KieFileSystem kfs = kieServices.newKieFileSystem();
//        // 获取指定目录下的所有规则文件,其实可以用后面的//======之间的内容替换,
////        File directory = new File(droolsFilePathConfig.getPath());
////        if (directory.isDirectory()) {
////           processDirectory(directory, kfs, kieServices);
////        }
////=================================================================================
//        Files.walkFileTree(Paths.get(droolsFilePathConfig.getPath()), new SimpleFileVisitor<>() {
//            @Override
//            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
//                if (file.toString().endsWith(".drl")) {
//                    kfs.write(ResourceFactory.newFileResource(file.toFile()));
//                }
//                return FileVisitResult.CONTINUE;
//            }
//        });
////=================================================================================
//        KieBuilder kieBuilder = kieServices.newKieBuilder(kfs);
//        kieBuilder.buildAll();
//        KieModule kieModule = kieBuilder.getKieModule();
//        return kieServices.newKieContainer(kieModule.getReleaseId());
//    }
//
//    /**
//     * 多级目录递归处理
//     */
//    private void processDirectory(File directory, KieFileSystem kfs, KieServices kieServices) {
//        File[] files = directory.listFiles();
//        if (files != null) {
//            for (File file : files) {
//                if (file.isDirectory()) {
//                    // 递归处理子目录
//                    processDirectory(file, kfs, kieServices);
//                } else if (file.getName().endsWith(".drl")) {
//                    kfs.write("src/main/resources/" + file.getName(),
//                            kieServices.getResources().newFileSystemResource(file));
//                }
//            }
//        }
//    }
}
